package com.example.xposed_apk.Utils;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class BypassUtils {

    public static void hookVPNCheck(XC_LoadPackage.LoadPackageParam lpparam) {
        try {
            // 核心VPN检测绕过逻辑
            hookNetworkInterface(lpparam);       // 劫持网络接口信息
            hookNetworkCapabilities(lpparam);    // 修改网络能力检测
            hookVpnService(lpparam);              // 绕过VpnService检测

        } catch (Throwable t) {
            XposedBridge.log("[ERROR] Hook VPN检测失败: " + t.getMessage());
        }
    }

    public static void hookProxyCheck(XC_LoadPackage.LoadPackageParam lpparam) {
        try {
            hookSystemProperties(lpparam);   // 拦截系统代理设置
            hookDnsLookup(lpparam);         // 劫持DNS查询（合并代理和DNS检测）

        } catch (Throwable t) {
            XposedBridge.log("[ERROR] Hook代理检测失败: " + t.getMessage());
        }
    }

    private static void hookNetworkInterface(XC_LoadPackage.LoadPackageParam lpparam) {
        Class<?> networkInterfaceClass = XposedHelpers.findClass(
                "java.net.NetworkInterface",
                lpparam.classLoader
        );

        // 劫持网卡名称获取
        XposedBridge.hookAllMethods(networkInterfaceClass, "getName", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) {
                String originalName = (String) param.getResult();
                XposedBridge.log("[NetworkInterface] 原始名称: " + originalName);

                // 将VPN特征网卡名改为普通移动数据网卡名
                if ("tun0".equals(originalName) || "ppp0".equals(originalName)) {
                    param.setResult("rmnet_data0");  // 修改为常见移动数据接口名称
                    XposedBridge.log("[NetworkInterface] 修改后名称: rmnet_data0");
                }
            }
        });
    }

    private static void hookNetworkCapabilities(XC_LoadPackage.LoadPackageParam lpparam) {
        Class<?> networkCapabilitiesClass = XposedHelpers.findClass(
                "android.net.NetworkCapabilities",
                lpparam.classLoader
        );

        // 劫持网络传输类型检测
        XposedBridge.hookAllMethods(networkCapabilitiesClass, "hasTransport", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) {
                param.setResult(false);  // 强制返回false表示没有VPN传输特征
                XposedBridge.log("[NetworkCapabilities] 已禁用hasTransport检测");
            }
        });

        // 劫持网络能力位掩码生成
        XposedBridge.hookAllMethods(
                networkCapabilitiesClass,
                "appendStringRepresentationOfBitMaskToStringBuilder",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) {
                        param.args[1] = 0;  // 清除位掩码中的VPN相关标志位
                        XposedBridge.log("[NetworkCapabilities] 已清除网络能力位掩码");
                    }
                });
    }

    private static void hookVpnService(XC_LoadPackage.LoadPackageParam lpparam) {
        try {
            Class<?> vpnServiceClass = XposedHelpers.findClass(
                    "android.net.VpnService",
                    lpparam.classLoader
            );

            // 劫持VPN准备检查
            XposedBridge.hookAllMethods(vpnServiceClass, "prepare", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) {
                    param.setResult(null);  // 始终返回null表示不需要VPN权限
                    XposedBridge.log("[VpnService] prepare()始终返回null");
                }
            });

        } catch (Throwable t) {
            XposedBridge.log("[WARN] VpnService劫持失败: " + t.getMessage());
        }
    }

    private static void hookSystemProperties(XC_LoadPackage.LoadPackageParam lpparam) {
        Class<?> systemClass = XposedHelpers.findClass(
                "java.lang.System",
                lpparam.classLoader
        );

        // 劫持系统属性获取
        XposedHelpers.findAndHookMethod(
                systemClass,
                "getProperty",
                String.class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) {
                        String key = (String) param.args[0];
                        // 拦截代理相关系统属性
                        if (key != null &&
                                (key.contains("http.proxyHost") ||
                                        key.contains("http.proxyPort"))) {
                            param.setResult(null);  // 返回null隐藏代理设置
                            XposedBridge.log("[System] 已阻止代理属性: " + key);
                        }
                    }
                });
    }

    private static void hookDnsLookup(XC_LoadPackage.LoadPackageParam lpparam) {
        try {
            Class<?> inetAddressClass = XposedHelpers.findClass(
                    "java.net.InetAddress",
                    lpparam.classLoader
            );

            // 劫持DNS解析过程
            XposedBridge.hookAllMethods(inetAddressClass, "getAllByName", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) {
                    // 示例：强制返回特定IP（按需修改）
                    // String host = (String) param.args[0];
                    // param.setResult(new InetAddress[]{InetAddress.getByName("8.8.8.8")});

                    XposedBridge.log("[DNS] 已劫持DNS查询: " + param.args[0]);
                }
            });

        } catch (Throwable t) {
            XposedBridge.log("[WARN] DNS劫持失败: " + t.getMessage());
        }
    }

    // 增强型检测绕过（可选功能）
    public static void hookAdditionalChecks(XC_LoadPackage.LoadPackageParam lpparam) {
        try {
            // 劫持代理选择器示例
            Class<?> proxySelectorClass = XposedHelpers.findClass(
                    "java.net.ProxySelector",
                    lpparam.classLoader
            );

            XposedBridge.hookAllMethods(proxySelectorClass, "select", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) {
                    XposedBridge.log("[ProxySelector] 已阻止代理选择");
                    param.setResult(java.util.Collections.emptyList());  // 返回空代理列表
                }
            });

        } catch (Throwable t) {
            XposedBridge.log("[WARN] 增强检测劫持失败: " + t.getMessage());
        }
    }
}